package springboot.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import springboot.bean.Task;
import springboot.bean.TaskExample;
import springboot.dao.TaskDAO;
import springboot.netty.NettySer;
import springboot.netty.SimpleServerHandler;
import springboot.tools.KernelTools;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 该类作为调度软件崩盘时的恢复类
 * 正在进行的任务最多只有两个，在数据库中管理正在执行的任务，若任务没有被执行则不进行管理
 *
 */
@Slf4j
@Service
public class AgvService {
    public static final String V1="Vehicle-0001";
    public static final String V2="Vehicle-0002";
    KernelTools km = new KernelTools();
    String v1OrderName=null;
    String v2OrderName=null;
    int A1=0;int A2=0;
    int B1=0;int B2=0;
    int C1=0;int C2=0;
    int D1=0;int D2=0;
    int E1=0;int E2=0;
    int F1=0;int F2=0;
    int G1=0;int G2=0;
    @Autowired
    private TaskDAO taskDAO;

    TaskExample taskExample=null;
    TaskExample.Criteria criteria=null;
    Task task=null;

    /**
     * 更新任务的状态
     */
    @Scheduled(fixedDelay = 1000)
    public void changeAGVStatus(){
        if (G1==0){
            v1OrderName=km.getTranspotOrder(V1);
            A1=0;B1=0;C1=0;D1=0;E1=0;F1=0;
        }
        if (G2==0){
            v2OrderName=km.getTranspotOrder(V2);
            A2=0;B2=0;C2=0;D2=0;E2=0;F2=0;
        }
        /*agv1*/
        if(v1OrderName.startsWith("TASK")) {
            //获得地堆放货地点属性
            String code=km.getPropertyByOrder(v1OrderName,"code");
            String start=km.getPropertyByOrder(v1OrderName,"start");
            String end=km.getPropertyByOrder(v1OrderName,"end");
            String name=km.getPropertyByOrder(v1OrderName,"name");
            if (G1==0){
                /*将物料编码传递给plcHandler*/
                SimpleServerHandler.data[4]=(byte)(Integer.parseInt(code)/256);
                SimpleServerHandler.data[5]=(byte)(Integer.parseInt(code)%256);
                G1=1;
            }
            /*取货途中*/
            if(A1==0&&km.getDriveOrderOperation(v1OrderName).startsWith("Load") &&
               km.getDriveOrderState(v1OrderName).equals("TRAVELLING")&&
               !km.getPosition(V1).equals(km.getDriverOrderPoint(v1OrderName))){
                A1=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v1OrderName);
                task=new Task();
                task.setStatus(1);
                task.setAgv(1);
                task.setCode(Integer.parseInt(code));
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    A1=0;
                }
            }
            /*取货中*/
            if(B1==0&&km.getDriveOrderOperation(v1OrderName).startsWith("Load")&&
               km.getDriveOrderState(v1OrderName).equals("TRAVELLING")&&
               km.getPosition(V1).equals(km.getDriverOrderPoint(v1OrderName))){
                B1=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v1OrderName);
                task=new Task();
                task.setStatus(2);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    B1=0;
                }
            }
            /*放货行走*/
            if(C1==0&&km.getDriveOrderOperation(v1OrderName).startsWith("Unload")&&
               km.getDriveOrderState(v1OrderName).equals("TRAVELLING")&&
               !km.getPosition(V1).equals(km.getDriverOrderPoint(v1OrderName))){
                C1=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v1OrderName);
                task=new Task();
                task.setStatus(3);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    C1=0;
                }
            }
            /*放货*/
            if(D1==0&&km.getDriveOrderOperation(v1OrderName).startsWith("Unload")&&
               km.getDriveOrderState(v1OrderName).equals("TRAVELLING")&&
               km.getPosition(V1).equals(km.getDriverOrderPoint(v1OrderName))){
                D1=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v1OrderName);
                task=new Task();
                task.setStatus(4);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    D1=0;
                }
            }
            if (km.isLastState(v1OrderName)) {
                String v1orderStatus = km.getOrderStatus(v1OrderName);
                if(E1==0&&v1orderStatus.equals("FINISHED")) {
                    G1=0;
                    SimpleServerHandler.data[4]=(byte)0;
                    SimpleServerHandler.data[5]=(byte)0;
                    taskExample=new TaskExample();
                    criteria=taskExample.createCriteria();
                    criteria.andNameEqualTo(v1OrderName);
                    int i=taskDAO.deleteByExample(taskExample);
                    if (i!=1){
                        E1=0;
                        G1=1;
                    }
                }
                if(F1==0&&v1orderStatus.equals("FAILED")) {
                    G1=0;
                    SimpleServerHandler.data[4]=(byte)0;
                    SimpleServerHandler.data[5]=(byte)0;
                    taskExample=new TaskExample();
                    criteria=taskExample.createCriteria();
                    criteria.andNameEqualTo(v1OrderName);
                    int i=taskDAO.deleteByExample(taskExample);
                    if (i!=1){
                        F1=0;
                        G1=1;
                    }
                }
            }

        }
        /*agv2*/
        if(v2OrderName.startsWith("TASK")) {
            //获得地堆放货地点属性
            String code=km.getPropertyByOrder(v2OrderName,"code");
            String start=km.getPropertyByOrder(v2OrderName,"start");
            String end=km.getPropertyByOrder(v2OrderName,"end");
            String name=km.getPropertyByOrder(v2OrderName,"name");
            if (G2==0){
                /*将物料编码传递给plcHandler*/
                SimpleServerHandler.data[6]=(byte)(Integer.parseInt(code)/256);
                SimpleServerHandler.data[7]=(byte)(Integer.parseInt(code)%256);
                G2=1;
            }

            /*取货途中*/
            if(A2==0&&km.getDriveOrderOperation(v2OrderName).startsWith("Load") &&
               km.getDriveOrderState(v2OrderName).equals("TRAVELLING")&&
               !km.getPosition(V2).equals(km.getDriverOrderPoint(v2OrderName))){
                A2=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v2OrderName);
                task=new Task();
                task.setStatus(1);
                task.setAgv(2);
                task.setCode(Integer.parseInt(code));
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    A2=0;
                }
            }
            /*取货中*/
            if(B2==0&&km.getDriveOrderOperation(v2OrderName).startsWith("Load")&&
               km.getDriveOrderState(v2OrderName).equals("TRAVELLING")&&
               km.getPosition(V2).equals(km.getDriverOrderPoint(v2OrderName))){
                B2=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v2OrderName);
                task=new Task();
                task.setStatus(2);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    B2=0;
                }
            }
            /*放货行走*/
            if(C2==0&&km.getDriveOrderOperation(v2OrderName).startsWith("Unload")&&
               km.getDriveOrderState(v2OrderName).equals("TRAVELLING")&&
               !km.getPosition(V2).equals(km.getDriverOrderPoint(v2OrderName))){
                C2=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v2OrderName);
                task=new Task();
                task.setStatus(3);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    C1=0;
                }
            }
            /*放货*/
            if(D2==0&&km.getDriveOrderOperation(v2OrderName).startsWith("Unload")&&
               km.getDriveOrderState(v2OrderName).equals("TRAVELLING")&&
               km.getPosition(V2).equals(km.getDriverOrderPoint(v2OrderName))){
                D2=1;
                taskExample=new TaskExample();
                criteria=taskExample.createCriteria();
                criteria.andNameEqualTo(v2OrderName);
                task=new Task();
                task.setStatus(4);
                int i=taskDAO.updateByExampleSelective(task,taskExample);
                if (i!=1){
                    D2=0;
                }
            }
            if (km.isLastState(v2OrderName)) {
                String v2orderStatus = km.getOrderStatus(v2OrderName);
                if(E2==0&&v2orderStatus.equals("FINISHED")) {
                    G2=0;
                    SimpleServerHandler.data[6]=(byte)0;
                    SimpleServerHandler.data[7]=(byte)0;
                    taskExample=new TaskExample();
                    criteria=taskExample.createCriteria();
                    criteria.andNameEqualTo(v2OrderName);
                    int i=taskDAO.deleteByExample(taskExample);
                    if (i!=1){
                        E2=0;
                        G2=1;
                    }
                }
                if(F2==0&&v2orderStatus.equals("FAILED")) {
                    G2=0;
                    SimpleServerHandler.data[6]=(byte)0;
                    SimpleServerHandler.data[7]=(byte)0;
                    taskExample=new TaskExample();
                    criteria=taskExample.createCriteria();
                    criteria.andNameEqualTo(v2OrderName);
                    int i=taskDAO.deleteByExample(taskExample);
                    if (i!=1){
                        F2=0;
                        G2=1;
                    }
                }
            }

        }

    }

    TaskExample tx1=null;
    TaskExample.Criteria txc1=null;
    Task t1=null;
    TaskExample tx2=null;
    TaskExample.Criteria txc2=null;
    Task t2=null;
    KernelTools km1 = new KernelTools();
    /**
     *选取12345的任务，并在kernel中查找有没有这个任务名称
     *只管理任务在进行中的
     *
     * 有一个问题就是任务的创建和分配有时间差，所以要的单独判断5这个状态
     */
    @Scheduled(fixedDelay = 2000)
    public void createTask(){
        tx1=new TaskExample();
        txc1=tx1.createCriteria();
        txc1.andStatusBetween(1,5);
        List<Task> listCreate=taskDAO.selectByExample(tx1);
        if (listCreate.size()==2){
            t1=listCreate.get(0);
            t2=listCreate.get(1);
            if (km1.getTO(t1.getName())==null){//问题很严重，创建任务
                if (t1.getStatus()==5){
                    km1.CreateOrderOneStation(t1);
                }else if (t1.getStatus()==1){
                    km1.CreateOrderOneStation1(t1);
                }else if (t1.getStatus()==2||t1.getStatus()==3){//取货中崩了，就表示已经取到货物了
                    km1.onlyUnload(t1);
                }else {
                    taskDAO.deleteByPrimaryKey(t1.getId());
                    log.info("放货中,表示已经放货完成了,删除该任务");
                }
            }else{//看一下任务是否还在运行中，不运行就删除该记录
                String taskStatus = km1.getOrderStatus(t1.getName());
                if (taskStatus.equals("FINISHED")||taskStatus.equals("FAILED")){
                    taskDAO.deleteByPrimaryKey(t1.getId());
                }
            }
            if (km1.getTO(t2.getName())==null){
                if (t2.getStatus()==5){
                    km1.CreateOrderOneStation(t2);
                }else if (t2.getStatus()==1){
                    km1.CreateOrderOneStation1(t2);
                }else if (t2.getStatus()==2||t2.getStatus()==3){//取货中崩了，就表示已经取到货物了
                    km1.onlyUnload(t2);
                }else {
                    taskDAO.deleteByPrimaryKey(t2.getId());
                    log.info("放货中,表示已经放货完成了,删除该任务");
                }
            }else{//看一下任务是否还在运行中，不运行就删除该记录
                String taskStatus = km1.getOrderStatus(t1.getName());
                if (taskStatus.equals("FINISHED")||taskStatus.equals("FAILED")){
                    taskDAO.deleteByPrimaryKey(t1.getId());
                }
            }
        }else if (listCreate.size()==1){
            t1=listCreate.get(0);
            if (km1.getTO(t1.getName())==null){//崩了就创建任务
                if (t1.getStatus()==5){
                    km1.CreateOrderOneStation(t1);
                }else if (t1.getStatus()==1){
                    km1.CreateOrderOneStation1(t1);
                }else if (t1.getStatus()==2||t1.getStatus()==3){//取货中崩了，就表示已经取到货物了
                    km1.onlyUnload(t1);
                }else {
                    taskDAO.deleteByPrimaryKey(t1.getId());
                    log.info("放货中,表示已经放货完成了,删除该任务");
                }
            }else {//没崩就创建任务
                String taskStatus = km1.getOrderStatus(t1.getName());
                if (taskStatus.equals("FINISHED")||taskStatus.equals("FAILED")){
                    taskDAO.deleteByPrimaryKey(t1.getId());
                }
                //看一下任务是否还在运行中，不运行就删除该记录
                tx1=new TaskExample();
                txc1=tx1.createCriteria();
                txc1.andStatusEqualTo(0);
                List<Task> listElse=taskDAO.selectByExample(tx1);
                if (listElse.size()>0){
                    t2=listElse.get(0);
                    km1.CreateOrderOneStation(t2);
                    t2.setStatus(5);
                    taskDAO.updateByPrimaryKeySelective(t2);
                }
            }
        }else if (listCreate.size()==0){
            /*直接创建任务*/
            tx1=new TaskExample();
            txc1=tx1.createCriteria();
            txc1.andStatusEqualTo(0);
            List<Task> listElse=taskDAO.selectByExample(tx1);
            if (listElse.size()>0){
                t2=listElse.get(0);
                km1.CreateOrderOneStation(t2);
                t2.setStatus(5);
                taskDAO.updateByPrimaryKeySelective(t2);
            }
        }else {
            log.info("已经有两个任务在执行中,无需再创建");
        }
    }

    /**
     * 启动tcp-ip
     * @throws Exception
     */
    @PostConstruct
    public void firstStart() throws Exception {
        new NettySer().start(8010);
    }
}
